package com.cys.markdown.doc.admin.controller.project;

import com.cys.common.data.RespCodeEnum;
import com.cys.common.pojo.RespEntity;
import com.cys.common.util.base.MapUtil;
import com.cys.common.util.base.StringUtil;
import com.cys.markdown.doc.admin.common.annotation.CurrentUser;
import com.cys.markdown.doc.admin.controller.sys.DeptController;
import com.cys.markdown.doc.project.entity.ProjectRelUser;
import com.cys.markdown.doc.project.interfaces.entity.IProjectInfo;
import com.cys.markdown.doc.project.interfaces.entity.IProjectRelUser;
import com.cys.markdown.doc.project.interfaces.service.ProjectInfoService;
import com.cys.markdown.doc.project.interfaces.service.ProjectRelUserService;
import com.cys.mid.core.system.interfaces.entity.ISysUser;
import com.cys.mid.core.system.interfaces.service.SysUserService;
import com.github.pagehelper.PageInfo;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 设置项目权限-Controller
 *
 * @author caiyushen
 */
@Controller
@RequestMapping("/admin/project/setting")
@Transactional(rollbackFor = Exception.class)
public class SetPermissionController {

    private Logger logger = LoggerFactory.getLogger(DeptController.class);

    @Resource(name = "sysUserServiceImpl")
    private SysUserService sysUserService;

    @Resource(name = "projectInfoServiceImpl")
    private ProjectInfoService projectInfoService;

    @Resource(name = "projectRelUserServiceImpl")
    private ProjectRelUserService projectRelUserService;

    /**
     * 新增项目
     *
     * @param param-projectInfoName    项目名称
     * @param param-projectInfoContent 项目描述
     * @return
     */
    @PostMapping("/saveProject")
    @ResponseBody
    @RequiresPermissions("project_set:save")
    public RespEntity saveProject(@RequestParam Map param) throws Exception {
        if (!StringUtil.checkObj(param.get("projectInfoName"))) {
            logger.warn("method[saveProject] projectInfoName is null.");
            return new RespEntity(RespCodeEnum.deficiency);
        }
        projectInfoService.save(param);
        return new RespEntity(RespCodeEnum.success);
    }


    /**
     * 修改项目
     *
     * @param param-projectInfoId      项目主键
     * @param param-projectInfoName    项目名称
     * @param param-projectInfoContent 项目描述
     * @return
     */
    @PutMapping("/updateProject")
    @ResponseBody
    @RequiresPermissions("project_set:save")
    public RespEntity updateProject(@RequestParam Map param) throws Exception {
        if (!StringUtil.checkObj(param.get("projectInfoId"))) {
            logger.warn("method[updateProject] projectInfoId is null.");
            return new RespEntity(RespCodeEnum.deficiency);
        }
        if (!StringUtil.checkObj(param.get("projectInfoName"))) {
            logger.warn("method[updateProject] projectInfoName is null.");
            return new RespEntity(RespCodeEnum.deficiency);
        }
        projectInfoService.update(param);
        return new RespEntity(RespCodeEnum.success);
    }

    /**
     * 根据项目主键获取项目信息
     */
    @GetMapping("/getProjectById")
    @ResponseBody
    @RequiresPermissions("project_set:view")
    public RespEntity getProjectById(Long projectInfoId) {
        if (!StringUtil.checkObj(projectInfoId)) {
            logger.warn("method[getProjectById] projectInfoId is null.");
            return new RespEntity(RespCodeEnum.deficiency);
        }
        IProjectInfo projectInfo = projectInfoService.find(projectInfoId);
        return new RespEntity(RespCodeEnum.success, projectInfo);
    }

    /**
     * 删除项目
     *
     * @param projectInfoId 项目主键
     * @return
     */
    @DeleteMapping("/deleteProject")
    @ResponseBody
    @RequiresPermissions("project_set:save")
    public RespEntity deleteProject(Long projectInfoId) throws Exception {
        if (!StringUtil.checkObj(projectInfoId)) {
            logger.warn("method[deleteProject] projectInfoId is null.");
            return new RespEntity(RespCodeEnum.deficiency);
        }
        projectInfoService.logicDeleteById(projectInfoId);
        return new RespEntity(RespCodeEnum.success);
    }

    /**
     * 根据项目id获取未关联项目的用户分页列表  TODO
     *
     * @param pageNo              当前页
     * @param pageSize            当前页显示的数据量
     * @param param-sysUserName   用户名称
     * @param param-projectInfoId 项目主键
     * @return
     */
    @GetMapping("/getSysUserPage")
    @ResponseBody
    @RequiresPermissions("project_set:view")
    public RespEntity getSysUserPage(Integer pageNo, Integer pageSize, @RequestParam Map param) {
        PageInfo<ISysUser> pageInfo = projectRelUserService.findNotRelateUserPage(pageNo, pageSize, param);
        if (!CollectionUtils.isEmpty(pageInfo.getList())) {
            return new RespEntity(RespCodeEnum.success, pageInfo);
        }
        Map map = new HashMap();
        map.put("projectInfoId", MapUtil.getShortValue(param, "projectInfoId"));
        //新项目一个用户都没有关联的情况
        PageInfo<ISysUser> userPageInfo = sysUserService.findPage(pageNo, pageSize, param);
        return new RespEntity(RespCodeEnum.success, userPageInfo);

    }

    /**
     * 根据项目id获取用户分页列表
     *
     * @param pageNo        当前页
     * @param pageSize      当前页显示的数据量
     * @param sysUserName   用户名称
     * @param projectInfoId 工程信息主键
     * @return
     */
    @GetMapping("/getSysUserPageWithPro")
    @ResponseBody
    @RequiresPermissions("project_set:view")
    public RespEntity getSysUserPageWithPro(Integer pageNo, Integer pageSize, String sysUserName, Long projectInfoId) {
        if (!StringUtil.checkObj(projectInfoId)) {
            logger.warn("method[getSysUserPageWithPro] projectInfoId is null.");
            return new RespEntity(RespCodeEnum.deficiency);
        }
        PageInfo<ISysUser> pageInfo = projectRelUserService.findUserPageByProjectInfoId(pageNo, pageSize, projectInfoId, sysUserName);
        return new RespEntity(RespCodeEnum.success, pageInfo);
    }


    /**
     * 获取项目分页列表
     *
     * @param param-projectName 项目名称
     * @return
     */
    @GetMapping("/getProjectPage")
    @ResponseBody
    @RequiresPermissions("project_set:view")
    public RespEntity getProjectPage(Integer pageNo, Integer pageSize, @RequestParam Map param) {
        PageInfo<IProjectInfo> pageInfo = projectInfoService.findPage(pageNo, pageSize, param);
        return new RespEntity(RespCodeEnum.success, pageInfo);
    }

    /**
     * 获取父级项目列表
     *
     * @param param-projectName 项目名称
     * @return
     */
    @GetMapping("/getProjectList")
    @ResponseBody
    @RequiresPermissions("project_set:view")
    public RespEntity getProjectList(@RequestParam Map param) {
        List<IProjectInfo> dataList = projectInfoService.findParentList(param);
        return new RespEntity(RespCodeEnum.success, dataList);
    }

    /**
     * 获取用户列表
     */
    @GetMapping("/getSysUserList")
    @ResponseBody
    @RequiresPermissions("project_set:view")
    public RespEntity getSysUserList(@RequestParam Map param) {
        List<ISysUser> dataList = sysUserService.findList(param);
        return new RespEntity(RespCodeEnum.success, dataList);
    }


    /**
     * 根据用户id获取项目列表
     *
     * @param sysUserId 系统用户主键
     * @return
     */
    @GetMapping("/getProjectListBySysUserId")
    @ResponseBody
    @RequiresPermissions("project_set:view")
    public RespEntity getProjectListBySysUserId(Long sysUserId) {
        if (!StringUtil.checkObj(sysUserId)) {
            logger.warn("method[getProjectListBySysUserId] sysUserId is null.");
            return new RespEntity(RespCodeEnum.deficiency);
        }
        Map param = new HashMap();
        param.put("sysUserId", sysUserId);
        List<IProjectInfo> dataList = projectInfoService.findList(param);
        return new RespEntity(RespCodeEnum.success, dataList);
    }

    /**
     * 根据项目id获取用户列表
     *
     * @param projectInfoId 项目主键
     * @return
     */
    @GetMapping("/getUserListByProjectInfoId")
    @ResponseBody
    @RequiresPermissions("project_set:view")
    public RespEntity getUserListByProjectInfoId(Long projectInfoId) {
        if (!StringUtil.checkObj(projectInfoId)) {
            logger.warn("method[getUserListByProjectInfoId] projectInfoId is null.");
            return new RespEntity(RespCodeEnum.deficiency);
        }
        List<ISysUser> dataList = projectRelUserService.findUserListByProjectInfoId(projectInfoId);
        return new RespEntity(RespCodeEnum.success, dataList);
    }


    /**
     * 保存用户关联
     *
     * @param param-sysUserId        用户主键
     * @param param-projectInfoIdStr 项目主键，多个用英文逗号隔开
     * @param loginSysUserId         登录用户主键
     * @return
     */
    @PostMapping("/saveRelProject")
    @ResponseBody
    @RequiresPermissions("project_set:save")
    public RespEntity saveRelProject(@RequestParam Map param, @CurrentUser Long loginSysUserId) throws Exception {
        if (!StringUtil.checkObj(loginSysUserId)) {
            logger.warn("method[saveRelProject] loginSysUserId is null.");
            return new RespEntity(RespCodeEnum.session_timeout);
        }
        String projectInfoIdStr = MapUtil.getString(param, "projectInfoIdStr");
        if (!StringUtil.checkObj(projectInfoIdStr)) {
            logger.warn("method[saveRelProject] projectInfoIdStr is null.");
            return new RespEntity(RespCodeEnum.deficiency);
        }
        Long sysUserId = MapUtil.getLong(param, "sysUserId");
        if (!StringUtil.checkObj(sysUserId)) {
            logger.warn("method[saveRelProject] sysUserId is null.");
            return new RespEntity(RespCodeEnum.deficiency);
        }
        logger.info("method[saveRelProject] param:" + param.toString());
        List<Long> projectInfoIdList = Arrays.asList(projectInfoIdStr.split(",")).stream().map(s -> Long.parseLong(s.trim())).collect(Collectors.toList());
        projectRelUserService.saveBatchRelUser(projectInfoIdList, sysUserId);
        return new RespEntity(RespCodeEnum.success);
    }

    /**
     * 保存项目关联
     *
     * @param param-sysUserIdStr  用户主键，多个用英文逗号隔开
     * @param param-projectInfoId 项目主键
     * @param loginSysUserId      登录用户主键
     * @return
     */
    @PostMapping("/saveRelUser")
    @ResponseBody
    @RequiresPermissions("project_set:save")
    public RespEntity saveRelUser(@RequestParam Map param, @CurrentUser Long loginSysUserId) throws Exception {
        if (!StringUtil.checkObj(loginSysUserId)) {
            logger.warn("method[saveRelUser] loginSysUserId is null.");
            return new RespEntity(RespCodeEnum.session_timeout);
        }
        String sysUserIdStr = MapUtil.getString(param, "sysUserIdStr");
        if (!StringUtil.checkObj(sysUserIdStr)) {
            logger.warn("method[saveRelUser] sysUserIdStr is null.");
            return new RespEntity(RespCodeEnum.deficiency);
        }
        Long projectInfoId = MapUtil.getLong(param, "projectInfoId");
        if (!StringUtil.checkObj(projectInfoId)) {
            logger.warn("method[saveRelUser] projectInfoId is null.");
            return new RespEntity(RespCodeEnum.deficiency);
        }
        logger.info("method[saveRelUser] param:" + param.toString());
        List<Long> sysUserIdList = Arrays.asList(sysUserIdStr.split(",")).stream().map(s -> Long.parseLong(s.trim())).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(sysUserIdList)) {
            logger.warn("method[saveRelUser] sysUserIdList is null.");
            return new RespEntity(RespCodeEnum.deficiency);
        }
        //根据项目id获取关联id
        List<IProjectRelUser> projectRelUserList = projectRelUserService.findListByProjectInfoId(projectInfoId);
        if (!CollectionUtils.isEmpty(projectRelUserList)) {
            for (IProjectRelUser rel : projectRelUserList) {
                if (sysUserIdList.contains(rel.getSysUserId())) {
                    sysUserIdList.remove(rel.getSysUserId());
                }
            }
        }
        //直接添加关联
        projectRelUserService.saveBatchRelProject(projectInfoId, sysUserIdList);
        return new RespEntity(RespCodeEnum.success);
    }


    /**
     * 保存关联
     *
     * @param param-sysUserId     用户主键
     * @param param-projectInfoId 项目主键
     * @param loginSysUserId      登录用户主键
     * @return
     */
    @PostMapping("/saveRel")
    @ResponseBody
    @RequiresPermissions("project_set:save")
    public RespEntity saveRel(@RequestParam Map param, @CurrentUser Long loginSysUserId) throws Exception {
        if (!StringUtil.checkObj(loginSysUserId)) {
            logger.warn("method[saveRel] loginSysUserId is null.");
            return new RespEntity(RespCodeEnum.session_timeout);
        }
        Long sysUserId = MapUtil.getLong(param, "sysUserId");
        if (!StringUtil.checkObj(sysUserId)) {
            logger.warn("method[saveRel] sysUserId is null.");
            return new RespEntity(RespCodeEnum.deficiency);
        }
        Long projectInfoId = MapUtil.getLong(param, "projectInfoId");
        if (!StringUtil.checkObj(projectInfoId)) {
            logger.warn("method[saveRel] projectInfoId is null.");
            return new RespEntity(RespCodeEnum.deficiency);
        }
        IProjectRelUser projectRelUser = projectRelUserService.find(sysUserId, projectInfoId);
        if (StringUtil.checkObj(projectRelUser)) {
            logger.info("method[saveRel] projectRelUser 已存在 param:" + param.toString());
            return new RespEntity(RespCodeEnum.success);
        }


        logger.info("method[saveRel] param:" + param.toString());
        projectRelUserService.save(param);
        return new RespEntity(RespCodeEnum.success);
    }

    /**
     * 根据项目主键、用户主键删除关联信息
     *
     * @param sysUserId     用户主键
     * @param projectInfoId 项目主键
     */
    @DeleteMapping("/deleteRelUser")
    @ResponseBody
    @RequiresPermissions("project_set:save")
    public RespEntity deleteRelUser(Long sysUserId, Long projectInfoId, @CurrentUser Long loginSysUserId) {
        if (!StringUtil.checkObj(loginSysUserId)) {
            return new RespEntity(RespCodeEnum.session_timeout);
        }
        if (!StringUtil.checkObj(sysUserId)) {
            logger.warn("method[deleteRelUser] sysUserId is null.");
            return new RespEntity(RespCodeEnum.deficiency);
        }
        if (!StringUtil.checkObj(projectInfoId)) {
            logger.warn("method[deleteRelUser] projectInfoId is null.");
            return new RespEntity(RespCodeEnum.deficiency);
        }
        IProjectRelUser projectRelUser = projectRelUserService.find(sysUserId, projectInfoId);
        if (!StringUtil.checkObj(projectRelUser)) {
            logger.warn("method[deleteRelUser] projectRelUser is null.");
            return new RespEntity(RespCodeEnum.deficiency);
        }
        projectRelUserService.deleteById(projectRelUser.getProjectRelUserId());
        return new RespEntity(RespCodeEnum.success);
    }

}
